#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "picturepuzzleitem.h"
#include "picturepuzzletool.h"
#include <QMessageBox>
#include <QPainter>
#include <QMouseEvent>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    init();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::init()
{
    QList<int> numbers;
     for(int i = 0; i < MapSize * MapSize; i++) {
         numbers.append(i);
     }
     std::random_device rd;
     std::mt19937 rng(rd());
     std::shuffle(numbers.begin(), numbers.end(), rng);

    PicturePuzzleTool::getInstance().splitImage();
    for(int i = 0; i < MapSize * MapSize; i++)
    {
        PicturePuzzleItem* item = new PicturePuzzleItem(this, MapSize);
        m_items.append(item);
        item->setCurPos(numbers[i]);
        qDebug() << "num" <<  numbers[i];

        if(i == MapSize * MapSize - 1)
        {
            item->init(nullptr, i);
            m_blackItem =  item;
        }
        else
            item->init(PicturePuzzleTool::getInstance().getPixmap(i), i);
        qDebug() << "item" <<item->getIndex();
    }
    if(!m_items.isEmpty())
        setBlockSize(m_items[0]->getPixmap()->width(), m_items[0]->getPixmap()->height());
}

void MainWindow::disPlay()
{

}

bool MainWindow::isSucceed()
{
    for(auto it : m_items)
    {
        if(!it->isRight())
            return false;
    }
    return true;
}

void MainWindow::paintEvent(QPaintEvent *event) {
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setRenderHint(QPainter::SmoothPixmapTransform); // 启用抗锯齿

    // 计算绘制区域基准点（居中显示）
    qDebug() << "x y" << m_blockSizeX << " kongge " << m_blockSizeY;
    int startX = (width() - MapSize * m_blockSizeX)/2;
    int startY = (height() - MapSize * m_blockSizeY)/2;

    // 遍历所有拼图块进行绘制
    foreach (PicturePuzzleItem* item, m_items) {
        // 计算实际绘制坐标
        int posX = startX + item->m_curPosX * m_blockSizeX;
        int posY = startY + item->m_curPosY * m_blockSizeY;

        if(!item || !item->getPixmap())
        {
            break;
        }

        QPixmap scaledPix = item->getPixmap()->scaled(
            m_blockSizeX, m_blockSizeY,
            Qt::IgnoreAspectRatio,
            Qt::SmoothTransformation
        );

        // 绘制拼图块本体
        painter.drawPixmap(posX, posY, scaledPix);

//        // 绘制边框线（可选）
//        painter.setPen(Qt::gray);
//        painter.drawRect(posX, posY, m_blockSize, m_blockSize);
    }
}

void MainWindow::resizeEvent(QResizeEvent *event) {
    int minDimension = qMin(width(), height());
    m_blockSizeX = qBound(80, minDimension/MapSize, 400); // 限制最小80px，最大200px
    m_blockSizeY = qBound(80, minDimension/MapSize, 400);
    update();
}

void MainWindow::setBlockSize(int x, int y)
{
    m_blockSizeX = x;
    m_blockSizeY = y;

    qDebug() << "x y" << m_blockSizeX << " kongge " << m_blockSizeY;
}

void MainWindow::mousePressEvent(QMouseEvent *event) {
    QPoint clickPos = event->pos();

    // 1. 计算点击位置对应的逻辑网格坐标
    QRect centralRect = rect().adjusted(
        (width() - MapSize*m_blockSizeX)/2,
        (height() - MapSize*m_blockSizeY)/2,
        -(width() - MapSize*m_blockSizeX)/2,
        -(height() - MapSize*m_blockSizeY)/2
    );

    if (!centralRect.contains(clickPos)) return;

    int gridX = (clickPos.x() - centralRect.x()) / m_blockSizeX;
    int gridY = (clickPos.y() - centralRect.y()) / m_blockSizeY;

    int clickedIndex = findItemIndexByPos(gridX, gridY); //找到对应的下标
    qDebug() << "clicked" << clickedIndex;
    //if (clickedIndex == -1 || clickedIndex == m_blackItemIndex) return;

    if (!isAdjacentToBlank(clickedIndex)) return;

    swapWithBlank(clickedIndex);
    update(); // 触发界面刷新
    if(isSucceed())
    {
        QMessageBox msgBox;
        msgBox.setText("成功了！");
        msgBox.exec();
    }
}

int MainWindow::findItemIndexByPos(int gridX, int gridY) const {
    for (int i = 0; i < m_items.size(); ++i) {
        if (m_items[i]->m_curPosX == gridX && m_items[i]->m_curPosY == gridY)
            return i;
    }
    return -1;
}

bool MainWindow::isAdjacentToBlank(int index) const {
    const auto& target = m_items[index];

    return (abs(target->m_curPosX - m_blackItem->m_curPosX) +
            abs(target->m_curPosY - m_blackItem->m_curPosY)) == 1;
}

void MainWindow::swapWithBlank(int index) {
    std::swap(m_items[index]->m_curPosX,
             m_blackItem->m_curPosX);
    std::swap(m_items[index]->m_curPosY,
             m_blackItem->m_curPosY);
}

